<?php

require_once 'lib/RequestHandler.php';

class NdaRequestHandler extends RequestHandler
{
	var $ttm = array();
	var $atf = array();

	var $currentState = NULL;
	var $initialState = 'Default';
	var $defaultEvent = 'get';

	public function handle ()
	{
		// handle automata
		$event = isset($_GET['event']) ? $_GET['event'] : $this->defaultEvent;
		$this->currentState = isset($_GET['state']) ? $_GET['state'] : $this->initialState;

		$atf = isset($this->atf[$this->currentState][$event])
			? $this->atf[$this->currentState][$event]
			: array($this, 'goUnexpectedEvent');
		assert('is_callable($atf)');
		$nextState = call_user_func($atf, $event);
		if (!$nextState) $nextState = $this->currentState;
		if (!isset($this->atf[$nextState])) { /* 404? */ $nextState = $this->undefinedState($event, $nextState); }
		$this->currentState = $nextState;

		// handle state render
		$sv1 = $this->currentState.'!'.$event;
		$sv2 = $this->currentState;
		$sv3 = '_undefined';
		if     (isset($this->ttm[$sv1])) $stateView = $this->ttm[$sv1];
		elseif (isset($this->ttm[$sv2])) $stateView = $this->ttm[$sv2];
		else                             $stateView = $this->ttm[$sv3];
		$this->tpl->set('rh', $this);
		$this->tpl->set('events', $this->atf[$this->currentState]);
		$this->tpl->parse($stateView, 'body');
	} // end of method handle
	public function undefinedState ($event, $state)
	{
		assert("0 ;// $state");
		return $this->initialState;
	} // end of method undefinedState
	public function doActionTransition ($anotherState, $anotherEventType, $event)
	{
		assert('isset($this->atf[$anotherState][$anotherEventType])');
		assert('$this->atf[$anotherState][$anotherEventType]');
		return call_user_func($this->atf[$anotherState][$anotherEventType], $event);
	} // end of method doActionTransition
	public function doActionTransition1 ($anotherState, $anotherEventType, $event)
	{
		assert('isset($this->atf[$anotherState][$anotherEventType])');
		assert('$this->atf[$anotherState][$anotherEventType]');
		$url = $this->hrefTo($anotherState, $anotherEventType);
		request_redirect($url);
		die();
	} // end of method doActionTransition
	public function goUnexpectedEvent ($event)
	{
		assert("0 ;// unexpectd event [$event]");
		//return $this->initialState;
		return $this->doActionTransition($this->initialState, $this->defaultEvent, $event);
	} // end of method unexpectedEvent

	public function hrefTo ($state=NULL, $event=NULL, $params=NULL)
	{
		if (!isset($state)) $state = $this->initialState;
		if (!isset($event)) $event = $this->defaultEvent;

		$args = array('m'=>'update','state'=>$anotherState, 'event'=>$anotherEventType);
		if (is_array($params)) $args += $params;
		$url = '?'.http_build_query($args);
		return $url;
	} // end of method hrefTo
}

